package com.ibeeking.found.msg.rest.service.impl;

import com.ibeeking.found.common.config.prop.FileOssProp;
import com.ibeeking.found.common.constants.GlobalConstant;
import com.ibeeking.found.common.enums.mp.WxMpEventTypeEnum;
import com.ibeeking.found.common.enums.mp.WxMpSourceTypeEnum;
import com.ibeeking.found.common.utils.UserUtils;
import com.ibeeking.found.msg.rest.service.*;
import com.ibeeking.found.msg.service.common.bo.WxMpMenuBO;
import com.ibeeking.found.msg.service.common.bo.WxMpSourceBO;
import com.ibeeking.found.msg.service.common.dos.WxMpMenuDO;
import com.ibeeking.found.msg.service.common.param.WxMpMenuButtonParam;
import com.ibeeking.found.msg.service.common.param.WxMpMenuParam;
import com.ibeeking.found.msg.service.common.vo.MpMiniprogramVO;
import com.ibeeking.found.msg.service.common.vo.WxMpMenuDetailVO;
import com.ibeeking.found.msg.service.common.vo.WxMpMenuVO;
import com.ibeeking.found.msg.service.common.vo.WxMpSourceDetailPageVO;
import com.ibeeking.found.msg.service.mapper.WxMpMenuMapper;
import com.ibeeking.nematos.constants.enums.LogClassifyEnum;
import com.ibeeking.nematos.core.utils.SpringBeanUtil;
import com.ibeeking.nematos.exception.BusinessException;
import com.ibeeking.nematos.log.utils.LogUtils;
import com.ibeeking.nematos.utils.bean.BeanUtil;
import com.ibeeking.nematos.utils.data.Collections3;
import com.ibeeking.nematos.utils.data.StringUtils;
import com.ibeeking.nematos.utils.id.IdGenerator;
import com.ibeeking.nematos.utils.json.JsonUtils;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import me.chanjar.weixin.common.bean.menu.WxMenu;
import me.chanjar.weixin.common.bean.menu.WxMenuButton;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.mp.api.WxMpMenuService;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @ClassName WxMpMenuServiceImpl
 * @Description
 * @Author ibeeking
 * @Date 2021-02-02 19:10
 **/
@Service
public class WxMpMenuServiceImpl implements IWxMpMenuService {
    @Resource
    private IOpenService wxOpenServiceImpl;

    @Resource
    private WxMpMenuMapper wxMpMenuMapper;
    @Resource
    private IMpMiniprogramService mpMiniprogramService;
    @Resource
    private IWxMpSourceService wxMpSourceServiceImpl;
    @Resource
    private FileOssProp fileOssProp;

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean saveAndReleasea(Long userId, WxMpMenuParam param) {
        Long tenantId = UserUtils.getTenantID();
        WxMpMenuService menuService = wxOpenServiceImpl.getWxOpenMpService(tenantId).getMenuService();
        //替换菜单
        WxMenu wxMenu = modifyMenu(userId, param);
        try {
            menuService.menuCreate(wxMenu);
        } catch (WxErrorException e) {
            LogUtils.error(LogClassifyEnum.ERROR_LOG, "发布菜单异常：[{}]", JsonUtils.toJsonStr(wxMenu));
            throw new BusinessException(e.getMessage(), e);
        }
        return true;
    }

    @Override
    public WxMpMenuBO queryMenuById(Long id) {
        WxMpMenuDO wxMpMenuDO = wxMpMenuMapper.selectById(id);
        if(wxMpMenuDO == null ) throw new BusinessException("没有菜单发现");
        WxMpMenuBO menuBO = BeanUtil.convertBean(wxMpMenuDO, WxMpMenuBO.class);
        menuBO.setEventType(WxMpEventTypeEnum.getEnum(wxMpMenuDO.getMenuType()));
        menuBO.setSourceType(WxMpSourceTypeEnum.getEnum(wxMpMenuDO.getSourceType()));
        return menuBO;
    }

    @Override
    public WxMpMenuVO queryMenu(String appId) {
        WxMpMenuVO result = new WxMpMenuVO();
        result.setAppId(appId);
        List<WxMpMenuDO> wxMpMenuDos = wxMpMenuMapper.selectList(new LambdaQueryWrapper<>(WxMpMenuDO.class)
                .eq(WxMpMenuDO::getAppId, appId)
                .orderByAsc(WxMpMenuDO::getSort)
                .orderByDesc(WxMpMenuDO::getCreateTime)
        );
        if (Collections3.isEmpty(wxMpMenuDos)) {
            return result;
        }
        Map<Long, WxMpMenuDO> menuMap = wxMpMenuDos.parallelStream().collect(Collectors.toMap(WxMpMenuDO::getId, m -> m, (s, a) -> a));
        List<WxMpMenuDetailVO> wxMpMenuDetailVos = JsonUtils.jsonToList(wxMpMenuDos, WxMpMenuDetailVO.class);
        List<WxMpMenuDetailVO> menus = new ArrayList<>();
        if (!CollectionUtils.isEmpty(wxMpMenuDetailVos)) {
            wxMpMenuDetailVos.stream().forEach(t -> {
                t.setEventType(WxMpEventTypeEnum.getEnum(menuMap.get(t.getId()).getMenuType()));
                t.setSourceType(WxMpSourceTypeEnum.getEnum(menuMap.get(t.getId()).getSourceType()));

                if (WxMpEventTypeEnum.CLICK.getEvenType().equals(t.getEventType().getEvenType()) && null != menuMap.get(t.getId()).getSourceType()) {
                    //点击事件
                    if (WxMpSourceTypeEnum.PIC.getName().equals(t.getSourceType().getName())) {
                        //1-图片，
                        WxMpSourceBO wxMpSourceBO = wxMpSourceServiceImpl.querySourceById(Long.valueOf(t.getUnionKey()));
                        if (null != wxMpSourceBO) {
                            t.setUnionPath(fileOssProp.getHost().concat(wxMpSourceBO.getPath()));
                            t.setUnionName(wxMpSourceBO.getName());
                        }
                    } else if (WxMpSourceTypeEnum.VOICE.getName().equals(t.getSourceType().getName())) {
                        //2-语音，
                        WxMpSourceBO wxMpSourceBO = wxMpSourceServiceImpl.querySourceById(Long.valueOf(t.getUnionKey()));
                        if (null != wxMpSourceBO) {
                            t.setUnionPath(fileOssProp.getHost().concat(wxMpSourceBO.getPath()));
                            t.setUnionName(wxMpSourceBO.getName());
                        }
                    } else if (WxMpSourceTypeEnum.VIDEO.getName().equals(t.getSourceType().getName())) {
                        //3-视频，
                        WxMpSourceBO wxMpSourceBO = wxMpSourceServiceImpl.querySourceById(Long.valueOf(t.getUnionKey()));
                        if (null != wxMpSourceBO) {
                            t.setUnionPath(fileOssProp.getHost().concat(wxMpSourceBO.getPath()));
                            t.setUnionName(wxMpSourceBO.getName());
                        }
                    } else if (WxMpSourceTypeEnum.MUSIC.getName().equals(t.getSourceType().getName())) {
                        //4-音乐，
                        WxMpSourceBO wxMpSourceBO = wxMpSourceServiceImpl.querySourceById(Long.valueOf(t.getUnionKey()));
                        if (null != wxMpSourceBO) {
                            t.setUnionPath(fileOssProp.getHost().concat(wxMpSourceBO.getPath()));
                            t.setUnionName(wxMpSourceBO.getName());
                        }
                    } else if (WxMpSourceTypeEnum.IMAGE_TEXT.getName().equals(t.getSourceType().getName())) {
                        //4-图文，
                        WxMpSourceBO wxMpSourceBO = wxMpSourceServiceImpl.querySourceById(Long.valueOf(t.getUnionKey()));
                        if (null != wxMpSourceBO) {
                            List<WxMpSourceDetailPageVO> wxMpSourceDetailPageVOS = JsonUtils.jsonToList(wxMpSourceBO.getSourceDetail(), WxMpSourceDetailPageVO.class);
                            wxMpSourceDetailPageVOS.stream().forEach(mpSourceNewsVO -> {
                                WxMpSourceBO wxMpSourceBO1 = wxMpSourceServiceImpl.querySourceById(mpSourceNewsVO.getThumbMediaId());
                                if (null != wxMpSourceBO1 && StringUtils.isNotBlank(wxMpSourceBO1.getPath())) {
                                    mpSourceNewsVO.setThumbMediaUrl(fileOssProp.getHost().concat(wxMpSourceBO1.getPath()));
                                }
                            });
                            t.setSourceDetail(wxMpSourceDetailPageVOS);
                            t.setUnionPath(fileOssProp.getHost().concat(wxMpSourceBO.getPath()));
                        }
                    }
                } else if (WxMpEventTypeEnum.VIEW.getEvenType().equals(t.getEventType().getEvenType())) {
                    //跳转URL用户点击view

                } else if (WxMpEventTypeEnum.MINIPROGRAM.getEvenType().equals(t.getEventType().getEvenType())) {
                    //跳转小程序
                } else if (WxMpEventTypeEnum.SCANCODE_PUSH.getEvenType().equals(t.getEventType().getEvenType())) {
                    //扫码推事件用户点击按钮后，微信客户端将调起扫一扫工具
                } else if (WxMpEventTypeEnum.SCANCODE_WAIT_MSG.getEvenType().equals(t.getEventType().getEvenType())) {
                    //扫码推事件且弹出“消息接收中”提示框用户点击按钮后，微信客户端将调起扫一扫工具
                } else if (WxMpEventTypeEnum.PIC_SYS_PHOTO.getEvenType().equals(t.getEventType().getEvenType())) {
                    //弹出系统拍照发图用户点击按钮后
                } else if (WxMpEventTypeEnum.PIC_PHOTO_OR_ALBUM.getEvenType().equals(t.getEventType().getEvenType())) {
                    //弹出拍照或者相册发图用户点击按钮后，微信客户端将弹出选择器供用户选择“拍照”或者“从手机相册选择”。 用户选择后即走其他两种流程
                } else if (WxMpEventTypeEnum.PIC_WEI_XIN.getEvenType().equals(t.getEventType().getEvenType())) {
                    //微信客户端将调起微信相册
                } else if (WxMpEventTypeEnum.LOCATION_SELECT.getEvenType().equals(t.getEventType().getEvenType())) {
                    //弹出地理位置选择器
                } else if (WxMpEventTypeEnum.MEDIA_ID.getEvenType().equals(t.getEventType().getEvenType())) {
                    //下发消息（除文本消息）
                } else if (WxMpEventTypeEnum.VIEW_LIMITED.getEvenType().equals(t.getEventType().getEvenType())) {
                    //跳转图文消息
                }


                if (GlobalConstant.PARENT_ID.equals(t.getParentId())) {
                    menus.add(t);
                }
                wxMpMenuDetailVos.stream().forEach(t1 -> {
                    if (t.getId().equals(t1.getParentId())) {
                        if (null == t.getSubButtons()) {
                            t.setSubButtons(new ArrayList<>());
                        }
                        t.getSubButtons().add(t1);
                    }
                });
            });
        }
        result.setButtons(menus);
        return result;
    }

    private WxMenu modifyMenu(Long userId, WxMpMenuParam param) {
        wxMpMenuMapper.delete(new LambdaQueryWrapper<>(WxMpMenuDO.class).eq(WxMpMenuDO::getAppId, param.getAppId()));

        WxMenu wxMenu = new WxMenu();
        List<WxMenuButton> outButtons = new ArrayList<>();
        List<WxMpMenuDO> add = new ArrayList<>();
        List<WxMpMenuButtonParam> buttons = param.getButtons();
        for (int i = 0; i < buttons.size(); i++) {

            //保存数据库
            WxMpMenuDO wxMpMenuDO = new WxMpMenuDO();
            wxMpMenuDO.setId(IdGenerator.getId());
            wxMpMenuDO.setParentId(0L);
            wxMpMenuDO.setAppId(param.getAppId());
            wxMpMenuDO.setName(buttons.get(i).getName());
            wxMpMenuDO.setSort(i);
            wxMpMenuDO.setMenuType(buttons.get(i).getEventType().getEvenType());
            if (null != buttons.get(i).getSourceType()) {
                wxMpMenuDO.setSourceType(buttons.get(i).getSourceType().getCode());
            }
            wxMpMenuDO.setUnionKey(buttons.get(i).getUnionKey());
            wxMpMenuDO.setRoute(buttons.get(i).getRoute());
            wxMpMenuDO.setH5(buttons.get(i).getH5());
            wxMpMenuDO.setCreateBy(userId);
            add.add(wxMpMenuDO);
            List<WxMpMenuButtonParam> subButtons = buttons.get(i).getSubButtons();

            //推送公众号
            WxMenuButton wxMenuButton = new WxMenuButton();
            wxMenuButton.setName(buttons.get(i).getName());
            wxMenuButton.setKey(String.valueOf(wxMpMenuDO.getId()));
            Boolean hasChild = !Collections3.isEmpty(subButtons);
            if (!hasChild) {
                this.menuButton(wxMenuButton, buttons.get(i));
                continue;
            }
            List<WxMenuButton> innerButtons = new ArrayList<>();
            if (!Collections3.isEmpty(subButtons)) {
                for (int j = 0; j < subButtons.size(); j++) {
                    //保存数据库
                    WxMpMenuDO wxMpMenuDO1 = new WxMpMenuDO();
                    wxMpMenuDO1.setId(IdGenerator.getId());
                    wxMpMenuDO1.setParentId(wxMpMenuDO.getId());
                    wxMpMenuDO1.setAppId(param.getAppId());
                    wxMpMenuDO1.setName(subButtons.get(j).getName());
                    wxMpMenuDO1.setSort(j);
                    wxMpMenuDO1.setMenuType(subButtons.get(j).getEventType().getEvenType());
                    if (null != subButtons.get(j).getSourceType()) {
                        wxMpMenuDO1.setSourceType(subButtons.get(j).getSourceType().getCode());
                    }
                    wxMpMenuDO1.setUnionKey(subButtons.get(j).getUnionKey());
                    wxMpMenuDO1.setRoute(subButtons.get(j).getRoute());
                    wxMpMenuDO1.setH5(subButtons.get(j).getH5());
                    wxMpMenuDO1.setCreateBy(userId);
                    add.add(wxMpMenuDO1);

                    //推送公众号
                    WxMenuButton wxMenuButton1 = new WxMenuButton();
                    wxMenuButton1.setName(subButtons.get(j).getName());
                    wxMenuButton1.setKey(String.valueOf(wxMpMenuDO1.getId()));
                    this.menuButton(wxMenuButton1, subButtons.get(j));
                    innerButtons.add(wxMenuButton1);
                }
                wxMenuButton.setSubButtons(innerButtons);
            }
            outButtons.add(wxMenuButton);
        }
        wxMenu.setButtons(outButtons);
        wxMpMenuMapper.insertBatchSomeColumn(add);
        return wxMenu;
    }


    private void menuButton(WxMenuButton wxMenuButton, WxMpMenuButtonParam param) {
        if (WxMpEventTypeEnum.CLICK.getEvenType().equals(param.getEventType().getEvenType())) {
            //点击事件
            if (WxMpSourceTypeEnum.PIC.getName().equals(param.getSourceType().getName())) {
                //1-图片，
                String mediaId = wxMpSourceServiceImpl.uploadMediaToWx(Long.valueOf(param.getUnionKey()));
                wxMenuButton.setType(WxMpEventTypeEnum.MEDIA_ID.getEvenType());
                wxMenuButton.setMediaId(mediaId);
            } else if (WxMpSourceTypeEnum.VOICE.getName().equals(param.getSourceType().getName())) {
                //2-语音，
                String mediaId = wxMpSourceServiceImpl.uploadMediaToWx(Long.valueOf(param.getUnionKey()));
                wxMenuButton.setType(WxMpEventTypeEnum.MEDIA_ID.getEvenType());
                wxMenuButton.setMediaId(mediaId);
            } else if (WxMpSourceTypeEnum.VIDEO.getName().equals(param.getSourceType().getName())) {
                //3-视频，
                String mediaId = wxMpSourceServiceImpl.uploadMediaToWx(Long.valueOf(param.getUnionKey()));
                wxMenuButton.setType(WxMpEventTypeEnum.MEDIA_ID.getEvenType());
                wxMenuButton.setMediaId(mediaId);
            } else if (WxMpSourceTypeEnum.MUSIC.getName().equals(param.getSourceType().getName())) {
                //4-音乐，
                String mediaId = wxMpSourceServiceImpl.uploadMediaToWx(Long.valueOf(param.getUnionKey()));
                wxMenuButton.setType(WxMpEventTypeEnum.MEDIA_ID.getEvenType());
                wxMenuButton.setMediaId(mediaId);
            } else if (WxMpSourceTypeEnum.IMAGE_TEXT.getName().equals(param.getSourceType().getName())) {
                //5-图文，
                String mediaId = wxMpSourceServiceImpl.uploadMediaToWx(Long.valueOf(param.getUnionKey()));
                wxMenuButton.setType(WxMpEventTypeEnum.MEDIA_ID.getEvenType());
                wxMenuButton.setMediaId(mediaId);
            } else if (WxMpSourceTypeEnum.TEXT.getName().equals(param.getSourceType().getName())) {
                //5-文本，
                wxMenuButton.setType(WxMpEventTypeEnum.CLICK.getEvenType());
            }
        } else if (WxMpEventTypeEnum.VIEW.getEvenType().equals(param.getEventType().getEvenType())) {
            //跳转URL用户点击view
            wxMenuButton.setType(param.getEventType().getEvenType());
            wxMenuButton.setUrl(param.getUnionKey());
        } else if (WxMpEventTypeEnum.MINIPROGRAM.getEvenType().equals(param.getEventType().getEvenType())) {
            //跳转小程序
            MpMiniprogramVO view = mpMiniprogramService.view(Long.valueOf(param.getUnionKey()));
            wxMenuButton.setType(param.getEventType().getEvenType());
            wxMenuButton.setAppId(view.getAppId());
            wxMenuButton.setUrl(param.getH5());
            wxMenuButton.setPagePath(param.getRoute());
        } else if (WxMpEventTypeEnum.SCANCODE_PUSH.getEvenType().equals(param.getEventType().getEvenType())) {
            //扫码推事件用户点击按钮后，微信客户端将调起扫一扫工具
            wxMenuButton.setType(param.getEventType().getEvenType());
        } else if (WxMpEventTypeEnum.SCANCODE_WAIT_MSG.getEvenType().equals(param.getEventType().getEvenType())) {
            //扫码推事件且弹出“消息接收中”提示框用户点击按钮后，微信客户端将调起扫一扫工具
            wxMenuButton.setType(param.getEventType().getEvenType());
        } else if (WxMpEventTypeEnum.PIC_SYS_PHOTO.getEvenType().equals(param.getEventType().getEvenType())) {
            //弹出系统拍照发图用户点击按钮后
            wxMenuButton.setType(param.getEventType().getEvenType());
        } else if (WxMpEventTypeEnum.PIC_PHOTO_OR_ALBUM.getEvenType().equals(param.getEventType().getEvenType())) {
            //弹出拍照或者相册发图用户点击按钮后，微信客户端将弹出选择器供用户选择“拍照”或者“从手机相册选择”。 用户选择后即走其他两种流程
            wxMenuButton.setType(param.getEventType().getEvenType());
        } else if (WxMpEventTypeEnum.PIC_WEI_XIN.getEvenType().equals(param.getEventType().getEvenType())) {
            //微信客户端将调起微信相册
            wxMenuButton.setType(param.getEventType().getEvenType());
        } else if (WxMpEventTypeEnum.LOCATION_SELECT.getEvenType().equals(param.getEventType().getEvenType())) {
            //弹出地理位置选择器
            wxMenuButton.setType(param.getEventType().getEvenType());
        } else if (WxMpEventTypeEnum.MEDIA_ID.getEvenType().equals(param.getEventType().getEvenType())) {
            //下发消息（除文本消息）
            wxMenuButton.setType(param.getEventType().getEvenType());
        } else if (WxMpEventTypeEnum.VIEW_LIMITED.getEvenType().equals(param.getEventType().getEvenType())) {
            //跳转图文消息
            wxMenuButton.setType(param.getEventType().getEvenType());
        }
    }

    private IWxMpMenuService getBean() {
        return SpringBeanUtil.getBean(IWxMpMenuService.class);
    }
}
